<html>
    <head>
        <title>定义当前租户</title>
    </head>
    <body>
        <script>
            /*
                1、定义当前租户  Determining the Current Tenant 

                                         多租户应用程序的第一件事是确定运行时的当前租户。

                                         ABP为此提供了一个可扩展的 "租户解析系统".

                                         然后在Multi-Tenancy 中间件中使用"租户解析系统"来确定当前HTTP请求的当前租户。


                                         (1)、租户解析器  Tenant Resolvers 

                                                  -1-- 默认租户解析器  Default Tenant Resolver

                                                        默认提供和配置以下解析器:

                                                              ①、CurrentUserTenantResolveContributor：
                                                                        
                                                                        如果当前用户已登录，则从当前用户的声明中获取租户ID。这应该始终是安全性的第一个贡献者。

                                                              ②、QueryStringTenantResolveContributor：尝试从查询字符串参数中查找当前租户ID。参数名称默认为__tenant。

                                                              ③、HeaderTenantResolveContributor：尝试从HTTP标头中查找当前租户ID。标头名称默认为__tenant。

                                                              ④、CookieTenantResolveContributor：尝试从cookie值中查找当前租户ID。默认情况下，cookie名称为__tenant。

                                                              ⑤、RouteTenantResolveContributor：尝试从路由（URL路径）中查找当前租户ID。
                                                              
                                                                                                变量名默认为__tenant。
                                                                                                
                                                                                                如果您使用此变量定义了路由，则它可以从路由中确定当前租户。

                                        

                                                  -2-- 域、子域租户解析器  Domain/Subdomain Tenant Resolvers
                                                                            
                                                         在实际应用程序中，大多数时候您希望通过子域（如mytenant1.mydomain.com）或 整个域（如mytenant.com）来确定当前租户。

                                                         如果是这样，您可以配置 "AbpTenantResolveOptions" 来添加域租户解析器。

                                                         eg:  添加子域解析器
                                                                            
                                                                Configure<AbpTenantResolveOptions>(options =>
                                                                {
                                                                    options.AddDomainTenantResolver("{0}.mydomain.com");
                                                                });

                                                            {0} 是确定当前租户唯一名称的占位符。

                                                            将此代码添加到模块的ConfigureServices方法中。

                                                            这应该在Web/API层中完成，因为URL是与Web相关的东西。


                                                            ★、关于独立验证服务器

                                                                        Openidduce是ABP中的默认身份验证服务器（自v6.0起）。
                                                                        
                                                                        当您使用OpenIdduce时，您还必须将此代码添加到PreConfigure方法中。
                                                            
                                                                                    // using Volo.Abp.OpenIddict.WildcardDomains

                                                                                    PreConfigure<AbpOpenIddictWildcardDomainOptions>(options =>
                                                                                    {
                                                                                        options.EnableWildcardDomainSupport = true;
                                                                                        options.WildcardDomainsFormat.Add("https://{0}.mydomain.com");
                                                                                    }); 

                                                                        您还必须将此代码添加到Configure方法中：

                                                                                    // using Volo.Abp.MultiTenancy;

                                                                                    Configure<AbpTenantResolveOptions>(options =>
                                                                                    {
                                                                                        options.AddDomainTenantResolver("{0}.mydomain.com");
                                                                                    });

                                                                        如果使用单独的身份验证服务器，则必须在HTTPApi.Host项目上安装
                                                                        
                                                                        [Owl.TokenWildcardIssuerValidator](https://www.nuget.org/packages/Owl.TokenWildcardIssuerValidator)：、、

                                                                                   dotnet add package Owl.TokenWildcardIssuerValidator

                                                                        然后修复.AddJwtBearer块：

                                                                                    // using using Owl.TokenWildcardIssuerValidator;

                                                                                    context.Services
                                                                                        .AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                                                                                        .AddJwtBearer(options =>
                                                                                        {
                                                                                            options.Authority = configuration["AuthServer:Authority"];
                                                                                            options.RequireHttpsMetadata = Convert.ToBoolean(configuration["AuthServer:RequireHttpsMetadata"]);
                                                                                            options.Audience = "ExampleProjectName";

                                                                                            // start of added  block
                                                                                            options.TokenValidationParameters.IssuerValidator = TokenWildcardIssuerValidator.IssuerValidator;
                                                                                            options.TokenValidationParameters.ValidIssuers = new[]
                                                                                            {
                                                                                                "https://{0}.mydomain.com:44349/" //the port may different
                                                                                            };
                                                                                            // end of added  block
                                                                                        });



                                                -3-- 自定义租户解析器

                                                            您可以添加实现自定义租户解析器，并在模块的ConfigureServices方法中配置AbpTenantResolveOptions，如下所示：
                                                            
                                                                                Configure<AbpTenantResolveOptions>(options =>
                                                                                {
                                                                                    options.TenantResolvers.Add(new MyCustomTenantResolveContributor());
                                                                                });

                                                            MyCustomTenantResolveContributor必须继承自TenantResolveContributorBase（或实现ITenantResolveContributor），
                                                            
                                                            如下所示：

                                                                                using System.Threading.Tasks;
                                                                                using Volo.Abp.MultiTenancy;

                                                                                namespace MultiTenancyDemo.Web
                                                                                {
                                                                                    public class MyCustomTenantResolveContributor : TenantResolveContributorBase
                                                                                    {
                                                                                        public override string Name => "Custom";

                                                                                        public override Task ResolveAsync(ITenantResolveContext context)
                                                                                        {
                                                                                            //TODO...
                                                                                        }
                                                                                    }
                                                                                }

                                                            租户解析器应该设置context.TenantIdOrName如果它可以确定它。如果不是，请保持原样以允许下一个解析器确定它。

                                                            context.ServiceProvider如果需要从依赖注入系统解析附加服务，可以使用。
            */
        </script>
    </body>
</html>